diff --git a/Cargo.lock b/Cargo.lock index dd0f2dad..6105b6a0 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -632,6 +632,12 @@ dependencies = [ "winapi", ] +[[package]] +name = "mopa" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a785740271256c230f57462d3b83e52f998433a7062fc18f96d5999474a9f915" + [[package]] name = "ntapi" version = "0.3.6" @@ -1358,6 +1364,7 @@ dependencies = [ "flate2", "lazy_static", "linked-hash-map", + "mopa", "num_cpus", "quick-xml 0.17.2", "regex", diff --git a/Cargo.toml b/Cargo.toml index 54dce47f..a38917e3 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,6 +23,7 @@ yaml-rust = "0.4" linked-hash-map = "0.5.3" tokio = { version = "1", features = ["full"] } num_cpus = "1.13.0" +mopa = "0.2.2" [target.x86_64-pc-windows-gnu] linker = "x86_64-w64-mingw32-gcc" diff --git a/src/detections/rule.rs b/src/detections/rule.rs index 92461e8c..945dfbf3 100644 --- a/src/detections/rule.rs +++ b/src/detections/rule.rs @@ -1,5 +1,7 @@ extern crate regex; +use mopa::mopafy; + use std::vec; use crate::detections::utils; @@ -135,16 +137,17 @@ impl RuleNode { return selection .unwrap() - .get_leaf_nodes() + .get_descendants() .iter() + .filter_map(|node| return node.downcast_ref::()) // mopaというライブラリを使うと簡単にダウンキャストできるらしいです。https://crates.io/crates/mopa .filter(|node| { - // alias.txtのevent_keyに一致するかどうか + // キーがEventIDのノードである let key = utils::get_event_id_key(); if node.get_key() == key { return true; } - // alias.txtのaliasに一致するかどうか + // EventIDのAliasに一致しているかどうか let alias = utils::get_alias(&key); if alias.is_none() { return false; @@ -175,11 +178,13 @@ impl DetectionNode { } // Ruleファイルの detection- selection配下のノードはこのtraitを実装する。 -trait SelectionNode { +trait SelectionNode: mopa::Any { fn select(&self, event_record: &Value) -> bool; fn init(&mut self) -> Result<(), Vec>; - fn get_leaf_nodes(&self) -> Vec<&LeafSelectionNode>; + fn get_childs(&self) -> Vec<&Box>; + fn get_descendants(&self) -> Vec<&Box>; } +mopafy!(SelectionNode); // detection - selection配下でAND条件を表すノード struct AndSelectionNode { @@ -230,17 +235,26 @@ impl SelectionNode for AndSelectionNode { } } - fn get_leaf_nodes(&self) -> Vec<&LeafSelectionNode> { + fn get_childs(&self) -> Vec<&Box> { let mut ret = vec![]; + self.child_nodes.iter().for_each(|child_node| { + ret.push(child_node); + }); + + return ret; + } + + fn get_descendants(&self) -> Vec<&Box> { + let mut ret = self.get_childs(); self.child_nodes .iter() - .map(|child| { - return child.get_leaf_nodes(); + .map(|child_node| { + return child_node.get_descendants(); }) .flatten() - .for_each(|descendant| { - ret.push(descendant); + .for_each(|descendant_node| { + ret.push(descendant_node); }); return ret; @@ -296,17 +310,26 @@ impl SelectionNode for OrSelectionNode { } } - fn get_leaf_nodes(&self) -> Vec<&LeafSelectionNode> { + fn get_childs(&self) -> Vec<&Box> { let mut ret = vec![]; + self.child_nodes.iter().for_each(|child_node| { + ret.push(child_node); + }); + + return ret; + } + + fn get_descendants(&self) -> Vec<&Box> { + let mut ret = self.get_childs(); self.child_nodes .iter() - .map(|child| { - return child.get_leaf_nodes(); + .map(|child_node| { + return child_node.get_descendants(); }) .flatten() - .for_each(|descendant| { - ret.push(descendant); + .for_each(|descendant_node| { + ret.push(descendant_node); }); return ret; @@ -453,8 +476,12 @@ impl SelectionNode for LeafSelectionNode { .init(&match_key_list, &self.select_value); } - fn get_leaf_nodes(&self) -> Vec<&LeafSelectionNode> { - return vec![&self]; + fn get_childs(&self) -> Vec<&Box> { + return vec![]; + } + + fn get_descendants(&self) -> Vec<&Box> { + return vec![]; } } @@ -727,3 +754,5 @@ impl LeafMatcher for WhitelistFileMatcher { }; } } + +