diff --git a/src/detections/detection.rs b/src/detections/detection.rs index acf841c2..0d5a548a 100644 --- a/src/detections/detection.rs +++ b/src/detections/detection.rs @@ -1,7 +1,7 @@ extern crate csv; use crate::detections::configs; -use crate::detections::utils::write_color_buffer; +use crate::detections::utils::{write_color_buffer, get_output_str_path}; use termcolor::{BufferWriter, Color, ColorChoice}; use crate::detections::message::AlertMessage; @@ -21,10 +21,9 @@ use crate::yaml::ParseYaml; use hashbrown; use hashbrown::HashMap; use serde_json::Value; -use std::env; use std::fmt::Write; use std::path::{Path, PathBuf}; -use pathdiff::diff_paths; + use std::sync::Arc; use tokio::{runtime::Runtime, spawn, task::JoinHandle}; @@ -255,16 +254,16 @@ impl Detection { } else { None }; - let tmp_fmt_path = &PathBuf::from(&rule.rulepath).canonicalize().unwrap().display().to_string()[4..]; - let abs_rule_path = Path::new(tmp_fmt_path); - let fmted_rule_path_str = if configs::CONFIG.read().unwrap().args.rules.is_absolute() { - abs_rule_path.to_str().unwrap().to_string() + let conf = configs::CONFIG.read().unwrap(); + let abs_rule_path = &PathBuf::from(&rule.rulepath).canonicalize().unwrap().display().to_string()[4..]; + let file_opt_path = if conf.args.filepath.is_some() { + conf.args.filepath.as_ref().unwrap() } else { - diff_paths(abs_rule_path, &env::current_dir().unwrap()).unwrap().to_str().unwrap().replace("..\\", "").replace(".\\", "") + conf.args.directory.as_ref().unwrap() }; let detect_info = DetectInfo { - filepath: record_info.evtx_filepath.to_string(), - rulepath: fmted_rule_path_str, + filepath: get_output_str_path(file_opt_path, Path::new(&record_info.evtx_filepath)), + rulepath: get_output_str_path(&configs::CONFIG.read().unwrap().args.rules, Path::new(abs_rule_path)), level: rule.yaml["level"].as_str().unwrap_or("-").to_string(), computername: record_info.record["Event"]["System"]["Computer"] .to_string() @@ -308,16 +307,11 @@ impl Detection { None }; // canonicalizeを行った際に、windows環境で\\?\が必ず文字列として入ってしまう問題があったため先頭の4文字を除外している - let tmp_fmt_path = &PathBuf::from(&rule.rulepath).canonicalize().unwrap().display().to_string()[4..]; - let abs_rule_path = Path::new(tmp_fmt_path); - let fmted_rule_path_str = if configs::CONFIG.read().unwrap().args.rules.is_absolute() { - abs_rule_path.to_str().unwrap().to_string() - } else { - diff_paths(abs_rule_path, &env::current_dir().unwrap()).unwrap().to_str().unwrap().replace("..\\", "").replace(".\\", "") - }; + let abs_rule_path = &PathBuf::from(&rule.rulepath).canonicalize().unwrap().display().to_string()[4..]; + let detect_info = DetectInfo { filepath: "-".to_owned(), - rulepath: fmted_rule_path_str, + rulepath: get_output_str_path(&configs::CONFIG.read().unwrap().args.rules, Path::new(abs_rule_path)), level: rule.yaml["level"].as_str().unwrap_or("").to_owned(), computername: "-".to_owned(), eventid: "-".to_owned(), diff --git a/src/detections/utils.rs b/src/detections/utils.rs index 1dec5959..875658ec 100644 --- a/src/detections/utils.rs +++ b/src/detections/utils.rs @@ -4,9 +4,12 @@ extern crate regex; use crate::detections::configs; use crate::detections::configs::CURRENT_EXE_PATH; +use std::env; use std::path::Path; use std::path::PathBuf; +use lazy_static::lazy_static; +use pathdiff::diff_paths; use termcolor::Color; use tokio::runtime::Builder; @@ -27,6 +30,10 @@ use termcolor::{BufferWriter, ColorSpec, WriteColor}; use super::detection::EvtxRecordInfo; +lazy_static! { + pub static ref OUTPUT_OMIT_REGEX:Regex = Regex::new(r"\.\./|\./|\.\.\\\\|\.\\|\.\.\\").unwrap(); +} + pub fn concat_selection_key(key_list: &[String]) -> String { return key_list .iter() @@ -386,11 +393,26 @@ pub fn check_setting_path(base_path: &Path, path: &str) -> PathBuf { } } +/// 与えられたoption_pathが相対パスであるかを確認し、絶対パスであればそのまま絶対パスのまま文字列として返却を行い、 +/// 相対パスであれば、カレントディレクトリとの相対パスの文字列から不要な(./、../)を除外した文字列を返却する関数 +pub fn get_output_str_path(option_path: &Path, target_path: &Path) -> String { + if option_path.is_absolute() { + target_path.to_str().unwrap().to_string() + } else { + let diff_path_result = diff_paths(target_path, &env::current_dir().unwrap()); + if let Some(diff_path) = diff_path_result { + OUTPUT_OMIT_REGEX.replace_all(diff_path.to_str().unwrap(), "").to_string() + } else { + OUTPUT_OMIT_REGEX.replace_all(target_path.to_str().unwrap(), "").to_string() + } + } +} + #[cfg(test)] mod tests { use std::path::Path; - use crate::detections::utils::{self, check_setting_path, make_ascii_titlecase}; + use crate::detections::utils::{self, check_setting_path, make_ascii_titlecase, get_output_str_path}; use regex::Regex; use serde_json::Value;