From ead69e78dc23ff37a9e235cf959893d10e849595 Mon Sep 17 00:00:00 2001 From: DastInDark <2350416+hitenkoku@users.noreply.github.com> Date: Tue, 19 Jul 2022 05:20:50 +0900 Subject: [PATCH] add: To create profile load process. #165 --- config/profiles.txt | 74 +++++++++++++++++------------------ src/options/mod.rs | 1 + src/options/profile.rs | 87 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 125 insertions(+), 37 deletions(-) create mode 100644 src/options/profile.rs diff --git a/config/profiles.txt b/config/profiles.txt index 0c44e42e..24ad1419 100644 --- a/config/profiles.txt +++ b/config/profiles.txt @@ -1,44 +1,44 @@ minimal: - Timestamp: %Timestamp% - Computer: %Computer% - Channel: %Channel% - EventID: %EventID% - Level: %Level% - RuleTitle: %RuleTitle% - Details: %Details% + Timestamp: '%Timestamp%' + Computer: '%Computer%' + Channel: '%Channel%' + EventID: '%EventID%' + Level: '%Level%' + RuleTitle: '%RuleTitle%' + Details: '%Details%' default: - Timestamp: %Timestamp% - Computer: %Computer% - Channel: %Channel% - EventID: %EventID% - Level: %Level% - Tags: %MitreAttack% - RecordID: %RecordID% - RuleTitle: %RuleTitle% - Details: %Details% + Timestamp: '%Timestamp%' + Computer: '%Computer%' + Channel: '%Channel%' + EventID: '%EventID%' + Level: '%Level%' + Tags: '%MitreAttack%' + RecordID: '%RecordID%' + RuleTitle: '%RuleTitle%' + Details: '%Details%' verbose-1: - Timestamp: %Timestamp% - Computer: %Computer% - Channel: %Channel% - EventID: %EventID% - Level: %Level% - Tags: %MitreAttack% - RecordID: %RecordID% - RuleTitle: %RuleTitle% - Details: %Details% - RulePath: %RulePath% - FilePath: %FilePath% + Timestamp: '%Timestamp%' + Computer: '%Computer%' + Channel: '%Channel%' + EventID: '%EventID%' + Level: '%Level%' + Tags: '%MitreAttack%' + RecordID: '%RecordID%' + RuleTitle: '%RuleTitle%' + Details: '%Details%' + RulePath: '%RulePath%' + FilePath: '%FilePath%' verbose-2: - Timestamp: %Timestamp% - Computer: %Computer% - Channel: %Channel% - EventID: %EventID% - Level: %Level% - Tags: %MitreAttack% - RecordID: %RecordID% - RuleTitle: %RuleTitle% - Details: %Details% - AllFieldInfo: %RecordInformation% \ No newline at end of file + Timestamp: '%Timestamp%' + Computer: '%Computer%' + Channel: '%Channel%' + EventID: '%EventID%' + Level: '%Level%' + Tags: '%MitreAttack%' + RecordID: '%RecordID%' + RuleTitle: '%RuleTitle%' + Details: '%Details%' + AllFieldInfo: '%RecordInformation%' \ No newline at end of file diff --git a/src/options/mod.rs b/src/options/mod.rs index 6841494b..f63dd2b9 100644 --- a/src/options/mod.rs +++ b/src/options/mod.rs @@ -1,2 +1,3 @@ pub mod level_tuning; +pub mod profile; pub mod update_rules; diff --git a/src/options/profile.rs b/src/options/profile.rs new file mode 100644 index 00000000..cfe41742 --- /dev/null +++ b/src/options/profile.rs @@ -0,0 +1,87 @@ +use crate::detections::configs::{self, CURRENT_EXE_PATH}; +use crate::detections::message::AlertMessage; +use crate::detections::utils::check_setting_path; +use crate::yaml; +use hashbrown::HashMap; +use lazy_static::lazy_static; +use std::path::Path; +use yaml_rust::{Yaml, YamlLoader}; + +lazy_static! { + pub static ref PROFILES: Option> = load_profile( + check_setting_path( + &CURRENT_EXE_PATH.to_path_buf(), + "config/default_profile.txt" + ) + .to_str() + .unwrap(), + check_setting_path( + &CURRENT_EXE_PATH.to_path_buf(), + "config/profiles.txt" + ) + .to_str() + .unwrap() + ); +} + +// 指定されたパスのprofileを読み込む処理 +fn read_profile_data(profile_path: &str) -> Result, String> { + let yml = yaml::ParseYaml::new(); + if let Ok(loaded_profile) = yml.read_file(Path::new(profile_path).to_path_buf()) { + match YamlLoader::load_from_str(&loaded_profile) { + Ok(profile_yml) => Ok(profile_yml), + Err(e) => Err(format!("Parse error: {}. {}", profile_path, e)) + } + } else { + Err(format!( + "Not exist profile file({}). Please check default profile.", + profile_path + )) + } +} + +/// プロファイル情報`を読み込む関数 +pub fn load_profile( + default_profile_path: &str, + profile_path: &str, +) -> Option> { + let conf = &configs::CONFIG.read().unwrap().args; + let profile_all: Vec = if conf.profile.is_none() { + match read_profile_data(default_profile_path) { + Ok(data) => data, + Err(e) => { + AlertMessage::alert(&e).ok(); + vec![] + } + } + } else { + match read_profile_data(profile_path) { + Ok(data) => data, + Err(e) => { + AlertMessage::alert(&e).ok(); + vec![] + } + } + }; + + // profileを読み込んで何も結果がない場合はAlert出しているためプログラム終了のためにNoneを出力する。 + if profile_all.is_empty() { + return None; + } + let profile_data = &profile_all[0]; + let mut ret: HashMap = HashMap::new(); + if let Some(profile_name) = &conf.profile { + if !profile_data[profile_name.as_str()].is_badvalue() { + profile_data[profile_name.as_str()].clone().as_hash().unwrap().into_iter().for_each(|(k, v)| { + ret.insert(k.as_str().unwrap().to_string(), v.as_str().unwrap().to_string()); + }); + Some(ret) + } else { + AlertMessage::alert(&format!("Invalid profile specified: {}", profile_name)).ok(); + None + } + } else { + AlertMessage::alert("Not specified --profile").ok(); + None + } +}