Add host event rules for bind and capability activity
This commit is contained in:
parent
b40ac4252c
commit
9784033f86
12 changed files with 316 additions and 8 deletions
9
tests/fixtures/sids/100073-interpreter-unusual-bind.json
vendored
Normal file
9
tests/fixtures/sids/100073-interpreter-unusual-bind.json
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"event": "bind",
|
||||
"pid": 4242,
|
||||
"ppid": 1,
|
||||
"uid": 1000,
|
||||
"comm": "python3",
|
||||
"local_ip": "0.0.0.0",
|
||||
"local_port": 4444
|
||||
}
|
||||
11
tests/fixtures/sids/100076-interpreter-unusual-accept.json
vendored
Normal file
11
tests/fixtures/sids/100076-interpreter-unusual-accept.json
vendored
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"event": "accept",
|
||||
"pid": 4242,
|
||||
"ppid": 1,
|
||||
"uid": 1000,
|
||||
"comm": "python3",
|
||||
"peer_ip": "8.8.8.8",
|
||||
"peer_port": 51515,
|
||||
"local_ip": "0.0.0.0",
|
||||
"local_port": 4444
|
||||
}
|
||||
8
tests/fixtures/sids/100077-interpreter-capset-sensitive.json
vendored
Normal file
8
tests/fixtures/sids/100077-interpreter-capset-sensitive.json
vendored
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
{
|
||||
"event": "capset",
|
||||
"pid": 4242,
|
||||
"ppid": 1,
|
||||
"uid": 1000,
|
||||
"comm": "python3",
|
||||
"capabilities": ["CAP_SYS_ADMIN"]
|
||||
}
|
||||
9
tests/fixtures/sids/100078-module-load-writable-path.json
vendored
Normal file
9
tests/fixtures/sids/100078-module-load-writable-path.json
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"event": "module_load",
|
||||
"pid": 4242,
|
||||
"ppid": 1,
|
||||
"uid": 0,
|
||||
"comm": "insmod",
|
||||
"path": "/tmp/evil.ko",
|
||||
"module_name": "evil"
|
||||
}
|
||||
|
|
@ -124,6 +124,44 @@ class TestRuleEventCompatibility(unittest.TestCase):
|
|||
"target_uid": "0",
|
||||
}))
|
||||
|
||||
def test_host_event_accepts_bind_accept_capset_and_module_shapes(self):
|
||||
self.assertIn(100073, self._sids({
|
||||
"type": "bind",
|
||||
"pid": "4242",
|
||||
"ppid": "1",
|
||||
"uid": "1000",
|
||||
"comm": "python3",
|
||||
"bind_ip": "0.0.0.0",
|
||||
"bind_port": "4444",
|
||||
}))
|
||||
self.assertIn(100076, self._sids({
|
||||
"event": "accept",
|
||||
"pid": 4242,
|
||||
"ppid": 1,
|
||||
"uid": 1000,
|
||||
"comm": "python3",
|
||||
"remote_ip": "8.8.8.8",
|
||||
"remote_port": "51515",
|
||||
"local_port": "4444",
|
||||
}))
|
||||
self.assertIn(100077, self._sids({
|
||||
"event": "capset",
|
||||
"pid": 4242,
|
||||
"ppid": 1,
|
||||
"uid": 1000,
|
||||
"comm": "python3",
|
||||
"capability": "CAP_SYS_ADMIN",
|
||||
}))
|
||||
self.assertIn(100078, self._sids({
|
||||
"event": "module_load",
|
||||
"pid": 4242,
|
||||
"ppid": 1,
|
||||
"uid": 0,
|
||||
"comm": "insmod",
|
||||
"path": "/tmp/evil.ko",
|
||||
"name": "evil",
|
||||
}))
|
||||
|
||||
def test_unknown_event_shape_still_errors(self):
|
||||
with self.assertRaisesRegex(
|
||||
ValueError, "event JSON must be an exec, syscall, or host event"
|
||||
|
|
|
|||
|
|
@ -24,6 +24,10 @@ class TestRuleOps(unittest.TestCase):
|
|||
self.assertIn(100070, sids)
|
||||
self.assertIn(100071, sids)
|
||||
self.assertIn(100072, sids)
|
||||
self.assertIn(100073, sids)
|
||||
self.assertIn(100076, sids)
|
||||
self.assertIn(100077, sids)
|
||||
self.assertIn(100078, sids)
|
||||
exec_rule = next(r for r in rules if r["sid"] == 100002)
|
||||
self.assertEqual(exec_rule["event"], "exec")
|
||||
self.assertIn("argv_regex", exec_rule["conditions"])
|
||||
|
|
@ -36,6 +40,9 @@ class TestRuleOps(unittest.TestCase):
|
|||
write_rule = next(r for r in rules if r["sid"] == 100069)
|
||||
self.assertEqual(write_rule["event"], "file_write")
|
||||
self.assertIn("path_prefixes", write_rule["conditions"])
|
||||
cap_rule = next(r for r in rules if r["sid"] == 100077)
|
||||
self.assertEqual(cap_rule["event"], "capset")
|
||||
self.assertIn("capabilities_any", cap_rule["conditions"])
|
||||
|
||||
def test_configured_exec_rule_is_listed(self):
|
||||
with tempfile.TemporaryDirectory() as d:
|
||||
|
|
@ -135,6 +142,51 @@ exec_comm = ["id"]
|
|||
}
|
||||
self.assertEqual(ruleops.test_event(cfg, event), [])
|
||||
|
||||
def test_matches_bind_accept_capset_and_module_load_events(self):
|
||||
cfg = Config()
|
||||
cases = (
|
||||
(100073, {
|
||||
"event": "bind",
|
||||
"pid": 42,
|
||||
"ppid": 1,
|
||||
"uid": 1000,
|
||||
"comm": "python3",
|
||||
"local_ip": "0.0.0.0",
|
||||
"local_port": 4444,
|
||||
}),
|
||||
(100076, {
|
||||
"event": "accept",
|
||||
"pid": 42,
|
||||
"ppid": 1,
|
||||
"uid": 1000,
|
||||
"comm": "python3",
|
||||
"peer_ip": "8.8.8.8",
|
||||
"peer_port": 51515,
|
||||
"local_ip": "0.0.0.0",
|
||||
"local_port": 4444,
|
||||
}),
|
||||
(100077, {
|
||||
"event": "capset",
|
||||
"pid": 42,
|
||||
"ppid": 1,
|
||||
"uid": 1000,
|
||||
"comm": "python3",
|
||||
"capabilities": ["CAP_SYS_ADMIN"],
|
||||
}),
|
||||
(100078, {
|
||||
"event": "module_load",
|
||||
"pid": 42,
|
||||
"ppid": 1,
|
||||
"uid": 0,
|
||||
"comm": "insmod",
|
||||
"path": "/tmp/evil.ko",
|
||||
"module_name": "evil",
|
||||
}),
|
||||
)
|
||||
for sid, event in cases:
|
||||
with self.subTest(sid=sid):
|
||||
self.assertIn(sid, {a.sid for a in ruleops.test_event(cfg, event)})
|
||||
|
||||
def test_render_markdown_documents_rules(self):
|
||||
text = ruleops.render_markdown(Config())
|
||||
self.assertIn("# Enodia Sentinel Event Rule Reference", text)
|
||||
|
|
|
|||
|
|
@ -20,7 +20,7 @@ class TestRegistry(unittest.TestCase):
|
|||
self.assertEqual(len(nums), len(set(nums)))
|
||||
|
||||
def test_count_and_helpers(self):
|
||||
self.assertEqual(len(sids.BUILTIN_SIDS), 62)
|
||||
self.assertEqual(len(sids.BUILTIN_SIDS), 66)
|
||||
self.assertEqual(
|
||||
sids.all_sids(), frozenset(s.sid for s in sids.BUILTIN_SIDS)
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue