refactor : rename variables and fix typo and add test (#270)
This commit is contained in:
@@ -11,7 +11,7 @@ use crate::detections::print::MESSAGES;
|
|||||||
use crate::detections::rule;
|
use crate::detections::rule;
|
||||||
use crate::detections::rule::RuleNode;
|
use crate::detections::rule::RuleNode;
|
||||||
use crate::detections::utils::get_serde_number_to_string;
|
use crate::detections::utils::get_serde_number_to_string;
|
||||||
use crate::fillter;
|
use crate::filter;
|
||||||
use crate::yaml::ParseYaml;
|
use crate::yaml::ParseYaml;
|
||||||
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@@ -55,12 +55,12 @@ impl Detection {
|
|||||||
pub fn parse_rule_files(
|
pub fn parse_rule_files(
|
||||||
level: String,
|
level: String,
|
||||||
rulespath: Option<&str>,
|
rulespath: Option<&str>,
|
||||||
fill_ids: &fillter::RuleFill,
|
exclude_ids: &filter::RuleExclude,
|
||||||
) -> Vec<RuleNode> {
|
) -> Vec<RuleNode> {
|
||||||
// ルールファイルのパースを実行
|
// ルールファイルのパースを実行
|
||||||
let mut rulefile_loader = ParseYaml::new();
|
let mut rulefile_loader = ParseYaml::new();
|
||||||
let result_readdir =
|
let result_readdir =
|
||||||
rulefile_loader.read_dir(rulespath.unwrap_or(DIRPATH_RULES), &level, fill_ids);
|
rulefile_loader.read_dir(rulespath.unwrap_or(DIRPATH_RULES), &level, exclude_ids);
|
||||||
if result_readdir.is_err() {
|
if result_readdir.is_err() {
|
||||||
AlertMessage::alert(
|
AlertMessage::alert(
|
||||||
&mut std::io::stderr().lock(),
|
&mut std::io::stderr().lock(),
|
||||||
@@ -275,7 +275,6 @@ impl Detection {
|
|||||||
fn test_parse_rule_files() {
|
fn test_parse_rule_files() {
|
||||||
let level = "informational";
|
let level = "informational";
|
||||||
let opt_rule_path = Some("./test_files/rules/level_yaml");
|
let opt_rule_path = Some("./test_files/rules/level_yaml");
|
||||||
let cole =
|
let cole = Detection::parse_rule_files(level.to_owned(), opt_rule_path, &filter::exclude_ids());
|
||||||
Detection::parse_rule_files(level.to_owned(), opt_rule_path, &fillter::exclude_ids());
|
|
||||||
assert_eq!(5, cole.len());
|
assert_eq!(5, cole.len());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
use crate::detections::configs;
|
|
||||||
use std::collections::HashSet;
|
|
||||||
use std::fs;
|
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct RuleFill {
|
|
||||||
pub no_use_rule: HashSet<String>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn exclude_ids() -> RuleFill {
|
|
||||||
let mut ids = String::from_utf8(fs::read("config/exclude-rules.txt").unwrap()).unwrap();
|
|
||||||
if !configs::CONFIG
|
|
||||||
.read()
|
|
||||||
.unwrap()
|
|
||||||
.args
|
|
||||||
.is_present("show-noisyalerts")
|
|
||||||
{
|
|
||||||
ids += "\n"; // 改行を入れないとexclude-rulesの一番最後の行とnoisy-rules.txtの一番最後の行が一行にまとめられてしまう。
|
|
||||||
ids += &String::from_utf8(fs::read("config/noisy-rules.txt").unwrap()).unwrap();
|
|
||||||
}
|
|
||||||
|
|
||||||
let mut fill_ids = RuleFill {
|
|
||||||
no_use_rule: HashSet::new(),
|
|
||||||
};
|
|
||||||
|
|
||||||
for v in ids.split_whitespace() {
|
|
||||||
let v = v.to_string();
|
|
||||||
if v.is_empty() {
|
|
||||||
// 空行は無視する。
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
fill_ids.no_use_rule.insert(v);
|
|
||||||
}
|
|
||||||
|
|
||||||
return fill_ids;
|
|
||||||
}
|
|
||||||
44
src/filter.rs
Normal file
44
src/filter.rs
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
use crate::detections::configs;
|
||||||
|
use std::collections::HashSet;
|
||||||
|
use std::fs;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct RuleExclude {
|
||||||
|
pub no_use_rule: HashSet<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn exclude_ids() -> RuleExclude {
|
||||||
|
let mut ids;
|
||||||
|
match fs::read("config/exclude-rules.txt") {
|
||||||
|
Ok(file) => ids = String::from_utf8(file).unwrap(),
|
||||||
|
Err(_) => panic!("config/exclude-rules.txt does not exist"),
|
||||||
|
};
|
||||||
|
|
||||||
|
if !configs::CONFIG
|
||||||
|
.read()
|
||||||
|
.unwrap()
|
||||||
|
.args
|
||||||
|
.is_present("show-noisyalerts")
|
||||||
|
{
|
||||||
|
ids += "\n"; // 改行を入れないとexclude-rulesの一番最後の行とnoisy-rules.txtの一番最初の行が一行にまとめられてしまう。
|
||||||
|
match fs::read("config/noisy-rules.txt") {
|
||||||
|
Ok(file) => ids += &String::from_utf8(file).unwrap(),
|
||||||
|
Err(_) => panic!("config/noisy-rules.txt does not exist"),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut exclude_ids = RuleExclude {
|
||||||
|
no_use_rule: HashSet::new(),
|
||||||
|
};
|
||||||
|
|
||||||
|
for v in ids.split_whitespace() {
|
||||||
|
let v = v.to_string();
|
||||||
|
if v.is_empty() {
|
||||||
|
// 空行は無視する。
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
exclude_ids.no_use_rule.insert(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
return exclude_ids;
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
pub mod afterfact;
|
pub mod afterfact;
|
||||||
pub mod detections;
|
pub mod detections;
|
||||||
pub mod fillter;
|
pub mod filter;
|
||||||
pub mod notify;
|
pub mod notify;
|
||||||
pub mod omikuji;
|
pub mod omikuji;
|
||||||
pub mod timeline;
|
pub mod timeline;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use evtx::{EvtxParser, ParserSettings};
|
|||||||
use hayabusa::detections::detection;
|
use hayabusa::detections::detection;
|
||||||
use hayabusa::detections::detection::EvtxRecordInfo;
|
use hayabusa::detections::detection::EvtxRecordInfo;
|
||||||
use hayabusa::detections::print::AlertMessage;
|
use hayabusa::detections::print::AlertMessage;
|
||||||
use hayabusa::fillter;
|
use hayabusa::filter;
|
||||||
use hayabusa::omikuji::Omikuji;
|
use hayabusa::omikuji::Omikuji;
|
||||||
use hayabusa::{afterfact::after_fact, detections::utils};
|
use hayabusa::{afterfact::after_fact, detections::utils};
|
||||||
use hayabusa::{detections::configs, timeline::timeline::Timeline};
|
use hayabusa::{detections::configs, timeline::timeline::Timeline};
|
||||||
@@ -133,7 +133,7 @@ fn analysis_files(evtx_files: Vec<PathBuf>) {
|
|||||||
let rule_files = detection::Detection::parse_rule_files(
|
let rule_files = detection::Detection::parse_rule_files(
|
||||||
level,
|
level,
|
||||||
configs::CONFIG.read().unwrap().args.value_of("rules"),
|
configs::CONFIG.read().unwrap().args.value_of("rules"),
|
||||||
&fillter::exclude_ids(),
|
&filter::exclude_ids(),
|
||||||
);
|
);
|
||||||
let mut pb = ProgressBar::new(evtx_files.len() as u64);
|
let mut pb = ProgressBar::new(evtx_files.len() as u64);
|
||||||
let mut detection = detection::Detection::new(rule_files);
|
let mut detection = detection::Detection::new(rule_files);
|
||||||
|
|||||||
50
src/yaml.rs
50
src/yaml.rs
@@ -3,7 +3,7 @@ extern crate yaml_rust;
|
|||||||
|
|
||||||
use crate::detections::configs;
|
use crate::detections::configs;
|
||||||
use crate::detections::print::AlertMessage;
|
use crate::detections::print::AlertMessage;
|
||||||
use crate::fillter::RuleFill;
|
use crate::filter::RuleExclude;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::ffi::OsStr;
|
use std::ffi::OsStr;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
@@ -47,14 +47,14 @@ impl ParseYaml {
|
|||||||
&mut self,
|
&mut self,
|
||||||
path: P,
|
path: P,
|
||||||
level: &str,
|
level: &str,
|
||||||
fill_ids: &RuleFill,
|
exclude_ids: &RuleExclude,
|
||||||
) -> io::Result<String> {
|
) -> io::Result<String> {
|
||||||
let mut entries = fs::read_dir(path)?;
|
let mut entries = fs::read_dir(path)?;
|
||||||
let yaml_docs = entries.try_fold(vec![], |mut ret, entry| {
|
let yaml_docs = entries.try_fold(vec![], |mut ret, entry| {
|
||||||
let entry = entry?;
|
let entry = entry?;
|
||||||
// フォルダは再帰的に呼び出す。
|
// フォルダは再帰的に呼び出す。
|
||||||
if entry.file_type()?.is_dir() {
|
if entry.file_type()?.is_dir() {
|
||||||
self.read_dir(entry.path(), level, fill_ids)?;
|
self.read_dir(entry.path(), level, exclude_ids)?;
|
||||||
return io::Result::Ok(ret);
|
return io::Result::Ok(ret);
|
||||||
}
|
}
|
||||||
// ファイル以外は無視
|
// ファイル以外は無視
|
||||||
@@ -140,7 +140,10 @@ impl ParseYaml {
|
|||||||
//除外されたルールは無視する
|
//除外されたルールは無視する
|
||||||
let rule_id = &yaml_doc["id"].as_str();
|
let rule_id = &yaml_doc["id"].as_str();
|
||||||
if rule_id.is_some() {
|
if rule_id.is_some() {
|
||||||
match fill_ids.no_use_rule.get(&rule_id.unwrap_or("").to_string()) {
|
match exclude_ids
|
||||||
|
.no_use_rule
|
||||||
|
.get(&rule_id.unwrap_or("").to_string())
|
||||||
|
{
|
||||||
None => (),
|
None => (),
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
self.ignorerule_count += 1;
|
self.ignorerule_count += 1;
|
||||||
@@ -160,9 +163,9 @@ impl ParseYaml {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
|
|
||||||
use crate::fillter;
|
use crate::filter;
|
||||||
use crate::yaml;
|
use crate::yaml;
|
||||||
use crate::yaml::RuleFill;
|
use crate::yaml::RuleExclude;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use yaml_rust::YamlLoader;
|
use yaml_rust::YamlLoader;
|
||||||
@@ -170,13 +173,13 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_read_dir_yaml() {
|
fn test_read_dir_yaml() {
|
||||||
let mut yaml = yaml::ParseYaml::new();
|
let mut yaml = yaml::ParseYaml::new();
|
||||||
let fill_ids = RuleFill {
|
let exclude_ids = RuleExclude {
|
||||||
no_use_rule: HashSet::new(),
|
no_use_rule: HashSet::new(),
|
||||||
};
|
};
|
||||||
let _ = &yaml.read_dir(
|
let _ = &yaml.read_dir(
|
||||||
"test_files/rules/yaml/".to_string(),
|
"test_files/rules/yaml/".to_string(),
|
||||||
&"".to_owned(),
|
&"".to_owned(),
|
||||||
&fill_ids,
|
&exclude_ids,
|
||||||
);
|
);
|
||||||
assert_ne!(yaml.files.len(), 0);
|
assert_ne!(yaml.files.len(), 0);
|
||||||
}
|
}
|
||||||
@@ -212,7 +215,7 @@ mod tests {
|
|||||||
fn test_default_level_read_yaml() {
|
fn test_default_level_read_yaml() {
|
||||||
let mut yaml = yaml::ParseYaml::new();
|
let mut yaml = yaml::ParseYaml::new();
|
||||||
let path = Path::new("test_files/rules/level_yaml");
|
let path = Path::new("test_files/rules/level_yaml");
|
||||||
yaml.read_dir(path.to_path_buf(), &"", &fillter::exclude_ids())
|
yaml.read_dir(path.to_path_buf(), &"", &filter::exclude_ids())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(yaml.files.len(), 5);
|
assert_eq!(yaml.files.len(), 5);
|
||||||
}
|
}
|
||||||
@@ -221,11 +224,7 @@ mod tests {
|
|||||||
fn test_info_level_read_yaml() {
|
fn test_info_level_read_yaml() {
|
||||||
let mut yaml = yaml::ParseYaml::new();
|
let mut yaml = yaml::ParseYaml::new();
|
||||||
let path = Path::new("test_files/rules/level_yaml");
|
let path = Path::new("test_files/rules/level_yaml");
|
||||||
yaml.read_dir(
|
yaml.read_dir(path.to_path_buf(), &"informational", &filter::exclude_ids())
|
||||||
path.to_path_buf(),
|
|
||||||
&"informational",
|
|
||||||
&fillter::exclude_ids(),
|
|
||||||
)
|
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(yaml.files.len(), 5);
|
assert_eq!(yaml.files.len(), 5);
|
||||||
}
|
}
|
||||||
@@ -233,7 +232,7 @@ mod tests {
|
|||||||
fn test_low_level_read_yaml() {
|
fn test_low_level_read_yaml() {
|
||||||
let mut yaml = yaml::ParseYaml::new();
|
let mut yaml = yaml::ParseYaml::new();
|
||||||
let path = Path::new("test_files/rules/level_yaml");
|
let path = Path::new("test_files/rules/level_yaml");
|
||||||
yaml.read_dir(path.to_path_buf(), &"LOW", &fillter::exclude_ids())
|
yaml.read_dir(path.to_path_buf(), &"LOW", &filter::exclude_ids())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(yaml.files.len(), 4);
|
assert_eq!(yaml.files.len(), 4);
|
||||||
}
|
}
|
||||||
@@ -241,7 +240,7 @@ mod tests {
|
|||||||
fn test_medium_level_read_yaml() {
|
fn test_medium_level_read_yaml() {
|
||||||
let mut yaml = yaml::ParseYaml::new();
|
let mut yaml = yaml::ParseYaml::new();
|
||||||
let path = Path::new("test_files/rules/level_yaml");
|
let path = Path::new("test_files/rules/level_yaml");
|
||||||
yaml.read_dir(path.to_path_buf(), &"MEDIUM", &fillter::exclude_ids())
|
yaml.read_dir(path.to_path_buf(), &"MEDIUM", &filter::exclude_ids())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(yaml.files.len(), 3);
|
assert_eq!(yaml.files.len(), 3);
|
||||||
}
|
}
|
||||||
@@ -249,7 +248,7 @@ mod tests {
|
|||||||
fn test_high_level_read_yaml() {
|
fn test_high_level_read_yaml() {
|
||||||
let mut yaml = yaml::ParseYaml::new();
|
let mut yaml = yaml::ParseYaml::new();
|
||||||
let path = Path::new("test_files/rules/level_yaml");
|
let path = Path::new("test_files/rules/level_yaml");
|
||||||
yaml.read_dir(path.to_path_buf(), &"HIGH", &fillter::exclude_ids())
|
yaml.read_dir(path.to_path_buf(), &"HIGH", &filter::exclude_ids())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(yaml.files.len(), 2);
|
assert_eq!(yaml.files.len(), 2);
|
||||||
}
|
}
|
||||||
@@ -257,16 +256,27 @@ mod tests {
|
|||||||
fn test_critical_level_read_yaml() {
|
fn test_critical_level_read_yaml() {
|
||||||
let mut yaml = yaml::ParseYaml::new();
|
let mut yaml = yaml::ParseYaml::new();
|
||||||
let path = Path::new("test_files/rules/level_yaml");
|
let path = Path::new("test_files/rules/level_yaml");
|
||||||
yaml.read_dir(path.to_path_buf(), &"CRITICAL", &fillter::exclude_ids())
|
yaml.read_dir(path.to_path_buf(), &"CRITICAL", &filter::exclude_ids())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(yaml.files.len(), 1);
|
assert_eq!(yaml.files.len(), 1);
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn test_exclude_rules_file() {
|
fn test_all_exclude_rules_file() {
|
||||||
let mut yaml = yaml::ParseYaml::new();
|
let mut yaml = yaml::ParseYaml::new();
|
||||||
let path = Path::new("test_files/rules/yaml");
|
let path = Path::new("test_files/rules/yaml");
|
||||||
yaml.read_dir(path.to_path_buf(), &"", &fillter::exclude_ids())
|
yaml.read_dir(path.to_path_buf(), &"", &filter::exclude_ids())
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(yaml.ignorerule_count, 10);
|
assert_eq!(yaml.ignorerule_count, 10);
|
||||||
}
|
}
|
||||||
|
#[test]
|
||||||
|
fn test_none_exclude_rules_file() {
|
||||||
|
let mut yaml = yaml::ParseYaml::new();
|
||||||
|
let path = Path::new("test_files/rules/yaml");
|
||||||
|
let exclude_ids = RuleExclude {
|
||||||
|
no_use_rule: HashSet::new(),
|
||||||
|
};
|
||||||
|
yaml.read_dir(path.to_path_buf(), &"", &exclude_ids)
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(yaml.ignorerule_count, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user