Skip to content

Commit

Permalink
Added features tests, multiline event input for testing. (#413)
Browse files Browse the repository at this point in the history
* Added features tests, multiline event input

* Adding erased license info

* Added basedir lookup and check

* Encapsulating features on functions, cleaning code

* Fixed overwrite test
  • Loading branch information
Zenidd authored and vikman90 committed Jun 27, 2019
1 parent 4b34fa9 commit 38a65e6
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 10 deletions.
9 changes: 9 additions & 0 deletions tools/rules-testing/decoders/test_decoders.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<decoder name="ow_test">
<program_name>^ow_test$</program_name>
</decoder>

<decoder name="test_same">
<program_name>^test_same_fields$</program_name>
<regex>User '(\w+)' logged from '(\d+.\d+.\d+.\d+)' (\d+) this is</regex>
<order>user, srcip, number</order>
</decoder>
50 changes: 50 additions & 0 deletions tools/rules-testing/rules/test_rules.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<group name="qa,test">

<!-- May 27 14:49:04 testUser ow_test[13244]: overwrite and list test -->
<!-- testing overwrite and list -->
<rule id="99900" level="5">
<match>overwrite and list test</match>
<description>Testing overwrite and list</description>
</rule>

<rule id="99900" level="7" overwrite="yes">
<match>overwrite and list test</match>
<list field="program_name" lookup="match_key">etc/lists/black_list</list>
<description>Successfully</description>
</rule>


<!-- Trigger alerts which depend on same_fields . Also it tests if_matched_sid -->
<!-- Dec 25 20:45:02 MyHost test_same_fields[12345]: User 'admin' logged from '192.168.1.100' 5 this is the same_fields test -->
<!-- Dec 25 20:45:02 MyHost test_same_fields[12345]: User 'admin' logged from '192.168.1.100' 5 this is the same_fields test -->
<!-- Dec 25 20:45:02 MyHost test_same_fields[12345]: User 'admin' logged from '192.168.1.100' 5 this is the same_fields test -->

<rule id="999205" level="3">
<match>this is the same_fields test</match>
<description>Testing same_fields</description>
</rule>

<rule id="999206" level="7" frequency="3" timeframe="300">
<if_matched_sid>999205</if_matched_sid>
<same_field>number</same_field>
<description>Same fields works</description>
</rule>


<!-- Trigger alerts which depend on not_same_fields . Also it tests if_matched_sid. -->
<!-- Dec 25 20:45:02 MyHost test_same_fields[12345]: User 'admin' logged from '192.168.1.100' 5 this is the not_same_fields test -->
<!-- Dec 25 20:45:02 MyHost test_same_fields[12345]: User 'admin' logged from '192.168.1.100' 6 this is the not_same_fields test -->
<!-- Dec 25 20:45:02 MyHost test_same_fields[12345]: User 'admin' logged from '192.168.1.100' 7 this is the not_same_fields test -->
<rule id="999207" level="3">
<match>this is the not_same_fields test</match>
<description>Testing not_same_fields</description>
</rule>

<rule id="999208" level="7" frequency="3" timeframe="300">
<if_matched_sid>999207</if_matched_sid>
<not_same_field>number</not_same_field>
<description>Not Same fields works</description>
</rule>


</group>
61 changes: 51 additions & 10 deletions tools/rules-testing/runtests.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,53 @@
import os
import sys
import os.path
from collections import OrderedDict
import shutil

class MultiOrderedDict(OrderedDict):
def __setitem__(self, key, value):
if isinstance(value, list) and key in self:
self[key].extend(value)
else:
super(MultiOrderedDict, self).__setitem__(key, value)

def getOssecConfig(initconf,path):
if os.path.isfile(path):
with open(path) as f:
for line in f.readlines():
key, value = line.rstrip("\n").split("=")
initconf[key] = value.replace("\"","")
if initconf["NAME"] != "Wazuh" or not os.path.exists(initconf["DIRECTORY"]):
print "Seems like there is no correct Wazuh installation "
sys.exit(1)
else:
print "Seems like there is no Wazuh installation or ossec-init.conf is missing."
sys.exit(1)

def provisionDR(bdir):
if os.path.isfile("./rules/test_rules.xml") and os.path.isfile("./decoders/test_decoders.xml"):
shutil.copy2("./rules/test_rules.xml", ossec_init["DIRECTORY"] + "/etc/rules")
shutil.copy2("./decoders/test_decoders.xml", ossec_init["DIRECTORY"] + "/etc/decoders")
else:
print "Test files are missing."
sys.exit(1)

def cleanDR(bdir):
if os.path.isfile(bdir + "/etc/rules/test_rules.xml") and os.path.isfile(bdir + "/etc/decoders/test_decoders.xml"):
os.remove(bdir + "/etc/rules/test_rules.xml")
os.remove(bdir + "/etc/decoders/test_decoders.xml")
else:
print "Could not clean rules and decoders test files"
sys.exit(1)

class OssecTester(object):
def __init__(self):
def __init__(self, bdir):
self._error = False
self._debug = False
self._quiet = False
self._ossec_conf = "/var/ossec/etc/ossec.conf"
self._base_dir = "/var/ossec/"
self._ossec_path = "/var/ossec/bin/"
self._ossec_conf = bdir + "/etc/ossec.conf"
self._base_dir = bdir
self._ossec_path = bdir + "/bin/"
self._test_path = "./tests"

def buildCmd(self, rule, alert, decoder):
Expand All @@ -32,9 +69,7 @@ def buildCmd(self, rule, alert, decoder):
cmd += ["-D", self._base_dir]
cmd += ['-U', "%s:%s:%s" % (rule, alert, decoder)]
return cmd

def runTest(self, log, rule, alert, decoder, section, name, negate=False):
#print self.buildCmd(rule, alert, decoder)
p = subprocess.Popen(
self.buildCmd(rule, alert, decoder),
stdout=subprocess.PIPE,
Expand All @@ -59,6 +94,7 @@ def runTest(self, log, rule, alert, decoder, section, name, negate=False):
print std_out
else:
sys.stdout.write(".")
sys.stdout.flush()

def run(self, selective_test=False):
for aFile in os.listdir(self._test_path):
Expand All @@ -67,7 +103,7 @@ def run(self, selective_test=False):
if selective_test and not aFile.endswith(selective_test):
continue
print "- [ File = %s ] ---------" % (aFile)
tGroup = ConfigParser.ConfigParser()
tGroup = ConfigParser.RawConfigParser(dict_type=MultiOrderedDict)
tGroup.read([aFile])
tSections = tGroup.sections()
for t in tSections:
Expand All @@ -85,7 +121,7 @@ def run(self, selective_test=False):
else:
neg = False
self.runTest(value, rule, alert, decoder,
t, name, negate=neg)
t, name, negate=neg)
print ""
if self._error:
sys.exit(1)
Expand All @@ -97,5 +133,10 @@ def run(self, selective_test=False):
selective_test += '.ini'
else:
selective_test = False
OT = OssecTester()
OT.run(selective_test)
ossec_init = {}
initconfigpath = "/etc/ossec-init.conf"
getOssecConfig(ossec_init, initconfigpath)
provisionDR(ossec_init["DIRECTORY"])
OT = OssecTester(ossec_init["DIRECTORY"])
OT.run(selective_test)
cleanDR(ossec_init["DIRECTORY"])
38 changes: 38 additions & 0 deletions tools/rules-testing/tests/features.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
[overwrite & list]
log 1 fail = May 27 14:49:04 testUser ow_test[13244]: overwrite and list test

rule = 99900
alert = 7
decoder = ow_test

[same fields]
log 1 pass = Dec 25 20:45:02 MyHost test_same_fields[12345]: User 'admin' logged from '192.168.1.100' 5 this is the same_fields test
log 1 pass = Dec 25 20:45:02 MyHost test_same_fields[12345]: User 'admin' logged from '192.168.1.100' 5 this is the same_fields test
log 1 pass = Dec 25 20:45:02 MyHost test_same_fields[12345]: User 'admin' logged from '192.168.1.100' 5 this is the same_fields test

rule = 999206
alert = 7
decoder = test_same

[not same fields]
log 1 pass = Dec 25 20:45:02 MyHost test_same_fields[12345]: User 'admin' logged from '192.168.1.100' 5 this is the not_same_fields test
log 1 pass = Dec 25 20:45:02 MyHost test_same_fields[12345]: User 'admin' logged from '192.168.1.100' 6 this is the not_same_fields test
log 1 pass = Dec 25 20:45:02 MyHost test_same_fields[12345]: User 'admin' logged from '192.168.1.100' 7 this is the not_same_fields test

rule = 999208
alert = 7
decoder = test_same

[sshd brute force rule]
log 1 pass = May 29 11:31:00 vagrant sshd[23119]: Failed password for invalid user adasdasd from 127.0.0.1 port 59264 ssh2
log 1 pass = May 29 11:31:00 vagrant sshd[23119]: Failed password for invalid user adasdasd from 127.0.0.1 port 59264 ssh2
log 1 pass = May 29 11:31:00 vagrant sshd[23119]: Failed password for invalid user adasdasd from 127.0.0.1 port 59264 ssh2
log 1 pass = May 29 11:31:00 vagrant sshd[23119]: Failed password for invalid user adasdasd from 127.0.0.1 port 59264 ssh2
log 1 pass = May 29 11:31:00 vagrant sshd[23119]: Failed password for invalid user adasdasd from 127.0.0.1 port 59264 ssh2
log 1 pass = May 29 11:31:00 vagrant sshd[23119]: Failed password for invalid user adasdasd from 127.0.0.1 port 59264 ssh2
log 1 pass = May 29 11:31:00 vagrant sshd[23119]: Failed password for invalid user adasdasd from 127.0.0.1 port 59264 ssh2
log 1 pass = May 29 11:31:00 vagrant sshd[23119]: Failed password for invalid user adasdasd from 127.0.0.1 port 59264 ssh2

rule = 5712
alert = 10
decoder = sshd

0 comments on commit 38a65e6

Please sign in to comment.